package org.example.nio.reactormodel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 多线程版本反应器
 *
 * @author hh
 * @since 2024/10/27
 */
public class MultiThreadEchoServerReactor {

    ServerSocketChannel serverSocket;
    AtomicInteger next = new AtomicInteger(0);
    // 选择器集合，引入多个选择器
    Selector[] selectors = new Selector[2];
    // 引入多个子反应器
    SubReactor[] subReactors = null;

    public MultiThreadEchoServerReactor() throws IOException {
        // 初始化多个选择器
        selectors[0] = Selector.open(); // 专门负责查询和分发新连接事件
        selectors[1] = Selector.open(); // 专门负责查询和分发IO传输事件
        serverSocket = ServerSocketChannel.open();
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", 9999);
        serverSocket.socket().bind(address);
        // 非阻塞
        serverSocket.configureBlocking(false);
        // 第一个选择器，负责监控新连接事件
        SelectionKey sk = serverSocket.register(selectors[0], SelectionKey.OP_ACCEPT);
        // 绑定Handler：新连接监控Handler绑定到SelectionKey(选择键)
        sk.attach(new AcceptorHandler(serverSocket, selectors[0]));
        // 第一个子反应器，负责第一个选择器的新连接事件分发（而不处理）
        SubReactor subReactor1 = new SubReactor(selectors[0]);
        // 第二个子反应器，负责第二个选择器的传输事件的分发（而不处理）
        SubReactor subReactor2 = new SubReactor(selectors[1]);
        subReactors = new SubReactor[]{subReactor1, subReactor2};
    }

    public void startService() {
        // 一个子反应器对应一个线程
        new Thread(subReactors[0]).start();
        new Thread(subReactors[1]).start();
    }

}
